
/**
 * 高精度计算工具类
 */
export class PrecisionMath {
  /**
   * 高精度加法
   */
  static add(a, b, precision = 5) {
    const factor = Math.pow(10, precision);
    return Math.round((a * factor + b * factor)) / factor;
  }

  /**
   * 高精度减法
   */
  static subtract(a, b, precision = 5) {
    const factor = Math.pow(10, precision);
    return Math.round((a * factor - b * factor)) / factor;
  }

  /**
   * 高精度乘法
   */
  static multiply(a, b, precision = 5) {
    const factor = Math.pow(10, precision);
    return Math.round(a * b * factor) / factor;
  }

  /**
   * 高精度除法
   */
  static divide(a, b, precision = 5) {
    if (b === 0) return 0;
    const factor = Math.pow(10, precision);
    return Math.round((a / b) * factor) / factor;
  }

  /**
   * 格式化为五位小数字符串
   */
  static toFixed5(number) {
    if (typeof number !== 'number' || isNaN(number)) return '0.00000';
    return number.toFixed(5);
  }

  /**
   * 安全的数字转换
   */
  static toNumber(value, defaultValue = 0) {
    const num = parseFloat(value);
    return isNaN(num) ? defaultValue : num;
  }
}

/**
 * 通用的面积计算函数（导出供外部使用）
 * @param {Array} xPoints - X坐标点数组
 * @param {Array} yPoints - Y坐标点数组
 * @returns {string} 格式化为五位小数的面积总和
 */
export const calculateArea = (xPoints, yPoints) => {
  const area = calculateAreaSum(xPoints, yPoints);
  return PrecisionMath.toFixed5(area);
}

export const cal = (params) => {
  const { accelerationTime, runningTime, totalTime, totalDistance, dwellTime, totalMass, reactionForce } = params

  // 加速时间和运动时间比值
  const acceleration = PrecisionMath.multiply(totalTime, PrecisionMath.divide(accelerationTime, runningTime))
  if (acceleration < 0.5) {
    
  } 

  // 匀速时间
  const constantSpeed = PrecisionMath.subtract(
    totalTime,
    PrecisionMath.multiply(2, acceleration),
  )

  // 绘制速度时间图
  const speedTimeXPoints = [
    0,
    acceleration,
    PrecisionMath.subtract(totalTime, acceleration),
    totalTime,
    PrecisionMath.add(totalTime, dwellTime),
  ]
  const speedTimeYPoints = [
    0,
    PrecisionMath.divide(totalDistance,
      PrecisionMath.subtract(totalTime, acceleration)
    ),
    PrecisionMath.divide(totalDistance,
      PrecisionMath.subtract(totalTime, acceleration)
    ),
    0,
    0,
  ]

  // 加速度
  const addSpeed = PrecisionMath.divide(
    totalDistance,
    PrecisionMath.multiply(PrecisionMath.subtract(totalTime, acceleration), acceleration)
  )
  // 加速度力
  const addForce = PrecisionMath.multiply(addSpeed, totalMass)

  // 力时间曲线图
  const forceTimeXPoints = [
    0,
    PrecisionMath.divide(acceleration, 2),
    acceleration,
    PrecisionMath.divide(totalTime, 2),
    PrecisionMath.subtract(totalTime, acceleration),
    PrecisionMath.subtract(totalTime,
      PrecisionMath.divide(acceleration, 2)),
    totalTime,
    PrecisionMath.add(totalTime, dwellTime),
  ]
  const forceTimeYPoints = [
    PrecisionMath.add(addForce, reactionForce),
    PrecisionMath.add(addForce, reactionForce),
    reactionForce,
    reactionForce,
    PrecisionMath.subtract(reactionForce, addForce),
    PrecisionMath.subtract(reactionForce, addForce),
    0,
    0,
  ]
  // 总循环周期
  const totalCycle = PrecisionMath.add(totalTime, dwellTime)

  // 峰值推力
  const peakForce = getAbsMax(forceTimeYPoints)

  // 持续推力（基于面积计算）
  const continuousForce = getContinuousForce(forceTimeXPoints, forceTimeYPoints)

  // 支持推力（通常等于持续推力）
  const supportForce = continuousForce

  return {
    acceleration: PrecisionMath.toFixed5(acceleration), // 加速时间、减速时间
    constantSpeed: PrecisionMath.toFixed5(constantSpeed), // 匀速时间
    totalCycle: PrecisionMath.toFixed5(totalCycle), // 总循环周期
    peakForce: PrecisionMath.toFixed5(peakForce), // 峰值推力
    continuousForce: PrecisionMath.toFixed5(continuousForce), // 持续推力
    supportForce: PrecisionMath.toFixed5(supportForce), // 支持推力

    // 图表数据
    speedTimeXPoints,
    speedTimeYPoints,
    forceTimeXPoints,
    forceTimeYPoints,
  }
}

// 计算数组中绝对值最大的值
function getAbsMax(arr) {
  return Math.max(...arr.map(Math.abs))
}

/**
 * 计算坐标图面积总和
 * 公式: 对于每个区间 |y| * (x1-x0)，然后求和
 * @param {Array} xPoints - X坐标点数组
 * @param {Array} yPoints - Y坐标点数组  
 * @returns {number} 面积总和
 */
function calculateAreaSum(xPoints, yPoints) {
  if (xPoints.length !== yPoints.length || xPoints.length < 2) {
    console.warn('坐标点数组长度不匹配或数据不足');
    return 0;
  }

  let totalArea = 0;

  // 遍历每个相邻的点对，计算矩形面积
  for (let i = 0; i < xPoints.length - 1; i++) {
    const x0 = PrecisionMath.toNumber(xPoints[i]);
    const x1 = PrecisionMath.toNumber(xPoints[i + 1]);
    const y = PrecisionMath.toNumber(yPoints[i]);

    // 计算区间宽度
    const width = PrecisionMath.subtract(x1, x0);

    // 计算面积: |y| * (x1-x0)
    const area = PrecisionMath.multiply(Math.abs(y), width);

    // 累加面积
    totalArea = PrecisionMath.add(totalArea, area);

    // 调试日志
    console.log(`区间${i}: x[${PrecisionMath.toFixed5(x0)}, ${PrecisionMath.toFixed5(x1)}], y=${PrecisionMath.toFixed5(y)}, 面积=${PrecisionMath.toFixed5(area)}`);
  }

  return totalArea;
}

/**
 * 计算持续推力（基于面积计算）
 * @param {Array} xarr - 时间坐标数组
 * @param {Array} yarr - 力坐标数组
 * @returns {number} 持续推力
 */
function getContinuousForce(xarr, yarr) {
  // 计算力-时间图的总面积
  const totalArea = calculateAreaSum(xarr, yarr);

  // 计算总时间（从第一个点到最后一个点）
  const totalTime = PrecisionMath.subtract(
    PrecisionMath.toNumber(xarr[xarr.length - 1]),
    PrecisionMath.toNumber(xarr[0])
  );

  // 持续推力 = 总面积 / 总时间
  const continuousForce = totalTime > 0 ? PrecisionMath.divide(totalArea, totalTime) : 0;

  console.log(`总面积: ${PrecisionMath.toFixed5(totalArea)}`);
  console.log(`总时间: ${PrecisionMath.toFixed5(totalTime)}`);
  console.log(`持续推力: ${PrecisionMath.toFixed5(continuousForce)}`);

  return continuousForce;
}